#ifndef TASKQUEUE_H
#define TASKQUEUE_H
#include <QQueue>
#include <QMutex>
#include <QWaitCondition>

// 任务队列中任务的类型
// 定义函数指针
typedef void (*callback)(void*);

// 任务的类型
struct Task
{
    // 函数指针
    callback function = NULL;
    // 函数参数, 保存函数调用的时候用到的实参
    void* arg = NULL;
};

// 用于存储客户端请求任务, 这个类也是一个单例模式的类
// 这个任务队列是要被多个线程访问, 因此需要进行线程同步
class TaskQueue
{
public:
    // 得到单例对象
    static TaskQueue* getInstance();
    // 1. 添加任务, 这些函数是由生产者调用的
    void addTask(Task &t);
    void addTask(callback func, void* arg);

    // 2. 拿出一个任务, 这个函数是由消费者调用的
    Task takeTask();

    // 3. 得到当前任务队列中的任务个数
    int taskNumber();

    // 4. 清空任务队列
    void taskClear();

private:
    TaskQueue();
    // 使用 Q_UNUSED 宏声明变量就不会提示变量没有被使用的警告信息了
    TaskQueue(const TaskQueue& t){Q_UNUSED(t)}

private:
    // 互斥锁
    QMutex m_mutex;
    // 添加条件变量对象, 用于阻塞线程(消费者性质的线程)
    QWaitCondition m_cond;
    QQueue<Task> m_taskQ;   // 多个线程可以共同访问的共享资源
    // 单例对象
    static TaskQueue m_queue;
};

#endif // TASKQUEUE_H
